package pro.lepers.portfolio.view.misc.cursor {
	import caurina.transitions.Equations;
	import caurina.transitions.Tweener;

	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.ui.Mouse;

	/**
	 * @author plepers
	 */
	public class Cursor extends Sprite {
		
		
		public var circle : MovieClip;
		
		public var icon : MovieClip;

		
		public function Cursor () {
			addEventListener( Event.ADDED_TO_STAGE, onAdded );
			addEventListener( Event.REMOVED_FROM_STAGE, onRemoved );
			mouseEnabled = mouseChildren = false;
		}

		private function onAdded( e : Event ) : void {
			addEventListener( Event.ENTER_FRAME, _oef );
			x = parent.mouseX + 0;
			y = parent.mouseY + 0;
		}
		
		private function onRemoved( e : Event ) : void {
			removeEventListener( Event.ENTER_FRAME, _oef );
		}

		private function _oef (event : Event) : void {
			x += ( parent.mouseX + 0 - x ) * .2;
			y += ( parent.mouseY + 0 - y ) * .2;
		}

		private function open () : void {
			icon.alpha = circle.alpha = 0;
			icon.scaleX = circle.scaleX = icon.scaleY = circle.scaleY = 0.4;
			Tweener.addTween( circle, { scaleX : 1, scaleY : 1, 			time : .4, transition : Equations.easeOutBack } );
			Tweener.addTween( circle, { alpha : 1, 							time : .4, transition : "linear" } );
			Tweener.addTween( icon, { delay : .1, scaleX : 1, scaleY : 1, 	time : .4, transition : Equations.easeOutBack } );
			Tweener.addTween( icon, { delay : .1, alpha : 1, 				time : .4, transition : "linear" } );
		}

		private function close () : void {
			Tweener.addTween( icon, { scaleX : .4, scaleY : .4, 				time : .1, transition : Equations.easeOutQuad } );
			Tweener.addTween( icon, { alpha : .1, 								time : .1, transition : "linear" } );
			Tweener.addTween( circle, { delay : .02, scaleX : .4, scaleY : .4, 	time : .1, transition : Equations.easeOutQuad } );
			Tweener.addTween( circle, { delay : .02, alpha : .1, 				time : .1, transition : "linear", onComplete : remove } );
		}

		private function remove () : void {
			if( parent )
				parent.removeChild( this );
		}

		
		//_____________________________________________________________________________
		//															  Static Management
		
		public static function _cinit ( stage : Stage ) : void {
			_stage = stage;
			_typeMap = __buildTypeMap( );
		}

		public static function setCursor ( type : int ) : void {
			
			var cClass : Class = _typeMap[ type ];
			removeCursor( );
			
			_currentCursorType = type;
			_currentCursor = new cClass() as Cursor;
			_stage.addChild( _currentCursor );
			_currentCursor.open( );
			
			Mouse.hide();
		}

		public static function removeCursor ( type : int = -1 ) : void {
			if( type != -1 && type != _currentCursorType ) return;
			if( _currentCursor )
				_currentCursor.close( );
			_currentCursor = null;
			_currentCursorType = -1;
			Mouse.show();
		}

		
		
		private static var _currentCursor : Cursor;
		private static var _currentCursorType : int = -1;
		
		private static var _stage : Stage;
		
		private static var _typeMap : Vector.<Class>;

		private static function __buildTypeMap () : Vector.<Class> {
			var res : Vector.<Class> = new Vector.<Class>( 5, true );
			
			res[ CursorType.CLOSE ] = CloseCursor_FC;
			return res;
		}
	}
}
